package io.joern.scanners.c

import io.joern.scanners.*
import io.joern.console.*
import io.joern.macros.QueryMacros.*
import io.shiftleft.semanticcpg.language.*

object GJB_8114_R_2_2_1 extends QueryBundle {

  implicit val resolver: ICallResolver = NoResolve

  @q
  def R_2_2_1(): Query =
    Query.make(
      name = "R_2_2_1",
      author = Crew.Sixpence,
      title = "禁止在构造函数中使用全局变量",
      description = """
                      |构造函数中直接访问全局变量可能导致程序行为不可预测。
                     """.stripMargin,
      score = 2,
      withStrRep({ cpg =>
        //val list = cpg.identifier.where(_.astParent.isFile).toList
        val vars = cpg.method.internal.name("<global>").flatMap(_.local).map(_.name).toList
        cpg.method
          .filter(m => m.name == m.astParentFullName && !(m.astParent.isNamespaceBlock))
          .filter(m => m.ast.isIdentifier.filter(x => !x.isLocal && !x.isMember).exists(x => vars.contains(x.name)))
      }),
      tags = List(QueryTags.default),
      codeExamples = CodeExamples(
        List("""
            |int globalVar = 10;
            |
            |class Base {
            |private:
            |    int a ;
            |public:
            |    Base() {
            |        this->a = globalVar;
            |    }
            |};
            |""".stripMargin),
        List("""
            |class Base {
            |private:
            |    int a ;
            |public:
            |    Base() {
            |        this->a = 100;
            |    }
            |};
            |""".stripMargin)
      )
    )
}
